using System;
using System.Linq;
using System.Security.Principal;
using System.ServiceProcess;
using InfiniTec.Security.Privileges;

namespace InfiniTec.ServiceProcess
{
	public class Service<T>
		where T: ServiceBase, IStartableAsApplication, new()
	{
		private readonly T _Service;

		public Service()
		{
			_Service = new T();
		}

		public void Start(params string[] requiredPrivileges)
		{
			var priviliges = new PrivilegeCollection();
			priviliges.Refresh();
			priviliges.ReducePrivilegesToMinimum(requiredPrivileges);

			var identity = WindowsIdentity.GetCurrent();
			var principal = new WindowsPrincipal(identity);
			var isLocalSystemUser = identity.User == new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);

			if (isLocalSystemUser ||
				principal.IsInRole(new SecurityIdentifier(WellKnownSidType.ServiceSid, null)))
			{
				var servicesToRun = new ServiceBase[]
				                    	{
				                    		_Service
				                    	};
				ServiceBase.Run(servicesToRun);
			}
			else
			{

				_Service.Start(Environment.GetCommandLineArgs().Skip(1).ToArray());
				Console.WriteLine("Service loaded. Hit <Return> to exit...");
				Console.ReadLine();
				_Service.Stop();
			}
		}
	}
}